﻿using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public static class RedisHelper
    {
        private static ConnectionMultiplexer connect;
        private static IDatabase redisDatabase;
        private static ISubscriber subscriber;

        private static string connection = @"";
        private static string redisNum = @"49";

        static  RedisHelper()
        {
            connect = ConnectionMultiplexer.ConnectAsync(connection).Result;
            redisDatabase = connect.GetDatabase(Convert.ToInt32(redisNum));
            subscriber = ConnectionMultiplexer.ConnectAsync(connection).Result.GetSubscriber();
            System.Threading.ThreadPool.SetMinThreads(200, 200);
        }

        /// <summary>
        /// 查询是否连接
        /// </summary>
        public static void CheckDatabase()
        {
            if (!connect.IsConnected)
            {
                connect = ConnectionMultiplexer.ConnectAsync(connection).Result;
                redisDatabase = connect.GetDatabase(Convert.ToInt32(redisNum));
                System.Threading.ThreadPool.SetMinThreads(200, 200);
            }
        }
        /// <summary>
        /// 移除key
        /// </summary>
        /// <param name="key"></param>
        public static void RemoveKey(string key)
        {
            CheckDatabase();
            redisDatabase.KeyDelete(key);
        }
        /// <summary>
        /// 添加key值并设置超时时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="time"></param>
        public static void SetKeyExprie(string key, string value, int time)
        {
            var span = new TimeSpan(0, time, 0);
            CheckDatabase();
            redisDatabase.StringSet(key, value, span);
        }
        /// <summary>
        /// 添加key值并设置超时时间-秒
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="time"></param>
        public static void SetKeyExprieForSeconds(string key, string value, int time)
        {
            var span = new TimeSpan(0, 0, time);
            CheckDatabase();
            redisDatabase.StringSet(key, value, span);
        }
        /// <summary>
        /// 设置键值对
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void SetKeyValue(string key, string value)
        {
            CheckDatabase();
            redisDatabase.StringSet(key, value);
        }
        /// <summary>
        /// 根据key得到value
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetKeyValue(string key)
        {
            CheckDatabase();
            return redisDatabase.StringGet(key).ToString();
        }
        /// <summary>
        /// 检查Key是否存在
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool CheckKeyExist(string key)
        {
            CheckDatabase();
            return redisDatabase.KeyExists(key);
        }


        /// <summary>
        /// 分布式--获取锁
        /// </summary>
        /// <param name="key"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool LockTake(string key, string token)
        {
            CheckDatabase();
            var span = new TimeSpan(0, 0, 5);
            var i = redisDatabase.LockTake(key, token, span);
            return i;
        }
        /// <summary>
        /// 分布式--释放锁
        /// </summary>
        /// <param name="key"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool LockRelease(string key, string token)
        {
            CheckDatabase();

            var i = redisDatabase.LockRelease(key, token);
            return i;
        }

      
        /// <summary>
        /// Redis过期监控
        /// </summary>
        public static void UnSubscribeRedis()
        {
            var channel = new RedisChannel("__keyevent@" + redisNum + "__:expired", RedisChannel.PatternMode.Auto);
            subscriber.Unsubscribe(channel);
        }
    }
}
